package extrace.ui.main.ui;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;

import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.CheckBox;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.Toast;

import com.amap.api.maps2d.AMap;
import com.amap.api.maps2d.CameraUpdate;
import com.amap.api.maps2d.CameraUpdateFactory;
import com.amap.api.maps2d.MapView;
import com.amap.api.maps2d.MapsInitializer;
import com.amap.api.maps2d.model.BitmapDescriptor;
import com.amap.api.maps2d.model.BitmapDescriptorFactory;
import com.amap.api.maps2d.model.LatLng;
import com.amap.api.maps2d.model.LatLngBounds;
import com.amap.api.maps2d.model.Marker;
import com.amap.api.maps2d.model.MarkerOptions;
import com.amap.api.maps2d.model.Polyline;
import com.amap.api.maps2d.model.PolylineOptions;
import com.amap.api.services.core.AMapException;
import com.amap.api.services.core.LatLonPoint;
import com.amap.api.services.route.BusRouteResult;
import com.amap.api.services.route.DrivePath;
import com.amap.api.services.route.DriveRoutePlanResult;

import com.amap.api.services.route.DriveRouteResult;
import com.amap.api.services.route.RidePath;
import com.amap.api.services.route.RideRouteResult;
import com.amap.api.services.route.RideStep;
import com.amap.api.services.route.RouteSearch;
import com.amap.api.services.route.RouteSearch.*;
import com.amap.api.services.route.WalkRouteResult;
import com.amap.api.track.AMapTrackClient;
import com.amap.api.track.query.entity.DriveMode;
import com.amap.api.track.query.entity.Point;
import com.amap.api.track.query.entity.Track;
import com.amap.api.track.query.entity.TrackPoint;
import com.amap.api.track.query.model.QueryTerminalRequest;
import com.amap.api.track.query.model.QueryTerminalResponse;
import com.amap.api.track.query.model.QueryTrackRequest;
import com.amap.api.track.query.model.QueryTrackResponse;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import extrace.misc.model.PackageRoute;
import extrace.ui.main.MainActivity;
import extrace.ui.main.R;

public class RouteFragment extends Fragment implements OnRouteSearchListener {
    private AMap aMap;
    private Context mContext;
    private MapView mapView;
    private ListView listView;
    private LatLonPoint mStartPoint = null;
    private LatLonPoint mEndPoint = null;
    private DriveRouteResult mDriveRouteResult;
    private boolean istracked = false;
    private  RouteSearch routeSearch;
    private AMapTrackClient aMapTrackClient;

    //=====================================================
    private List<Polyline> polylines = new LinkedList<>();
    private List<Marker> endMarkers = new LinkedList<>();
    private Constants constants = new Constants();
//========================================================

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.route, container, false);
//=====================================================
        aMapTrackClient = new AMapTrackClient(getContext());


        mContext = this.getContext();
        mapView = rootView.findViewById(R.id.map2);
        mapView.onCreate(savedInstanceState);// 此方法必须重写
        listView = rootView.findViewById(R.id.list);

        routeSearch = new RouteSearch(this.mContext);
        routeSearch.setRouteSearchListener(this);
        return rootView;
    }

    public void setItemID(String id) {
        constants.TERMINAL_NAME = id;
        istracked = false;

    }

    public void setroutes(ArrayList<LatLonPoint> latLonPoints) {

        mStartPoint = latLonPoints.get(0);
        mEndPoint = latLonPoints.get(1);

        init();

    }

    /**
     * 方法必须重写
     */
    @Override
    public void onResume() {
        super.onResume();
        mapView.onResume();
    }

    /**
     * 方法必须重写
     */
    @Override
    public void onPause() {
        super.onPause();
        mapView.onPause();
    }

    /**
     * 方法必须重写
     */
    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        mapView.onSaveInstanceState(outState);
    }

    /**
     * 方法必须重写
     */
    @Override
    public void onDestroy() {
//        setCameraPosition(aMap.getCameraPosition());//保存地图状态
        super.onDestroy();
        mapView.onDestroy();
    }

    //=======================================================
    //揽收打包派送点连接
    List<Map<String, Object>> lists ;
    SimpleDateFormat ft = new SimpleDateFormat("MM-dd hh:mm");
    public void drawRoutes(final List<PackageRoute> packageRoutes, final Integer status, List<String> address) {
        if (aMap == null) {
            aMap = mapView.getMap();
        }

        lists = new ArrayList<>();
//==================================================================
//        List<LatLonPoint> latLonPoints = new ArrayList<>();
//        List<LatLng> latLngs = new ArrayList<>();
        int i = 0;

        for (PackageRoute p : packageRoutes) {

            Map<String, Object> map = new HashMap<>();
//            latLonPoints.add(new LatLonPoint(p.getX(), p.getY()));

            MarkerOptions marker = new MarkerOptions();

            String title = "已揽收";
            int id = R.drawable.find_more_friend_photograph_icon;

            if (i == 0) {
                title = "已揽收";
                id = R.drawable.find_more_friend_photograph_icon;
                map.put("kuaidi", "快递已经" + address.get(i) + "揽收");
                map.put("date", ft.format(p.getTm()));
            } else if ((i > 0 && i < packageRoutes.size()&&status==1)||(i > 0 && i < packageRoutes.size()-1&&status==2)) {
                map.put("kuaidi", "快递已经" + address.get(i) + "打包");
                map.put("date", ft.format(p.getTm()));
                title = "已打包";
                id = R.drawable.find_more_friend_shake;

            } else if (status == 2 && i == packageRoutes.size()-1) {
                id = R.drawable.shoujian;
                title = "已交付";
                map.put("kuaidi", "快递已经" + address.get(i) + "交付");
                map.put("date", ft.format(p.getTm()));
            }


            Bitmap bitmap = Bitmap.createScaledBitmap(BitmapFactory.decodeResource(getResources(), id), 80, 80, true);
            marker.position(new LatLng(p.getX(), p.getY())).title(title).snippet(ft.format(p.getTm()));
            marker.icon(BitmapDescriptorFactory.fromBitmap(bitmap));
//=================================================================================
            if(i<packageRoutes.size()-1){
                final RouteSearch.FromAndTo fromAndTo = new RouteSearch.FromAndTo(new LatLonPoint(p.getX(), p.getY()), new LatLonPoint(packageRoutes.get(i+1).getX(), packageRoutes.get(i+1).getY()));
                RideRouteQuery query = new RideRouteQuery(fromAndTo);
                routeSearch.calculateRideRouteAsyn(query);}
//====================================================================================

            aMap.addMarker(marker).showInfoWindow();

            lists.add(map);
            i++;
        }
        if(istracked&&status==1){
            Map<String, Object> map = new HashMap<>();
            map.put("kuaidi", "快递正在派送");
            map.put("date", ft.format(System.currentTimeMillis()));

            lists.add(map);
        }
        List<Map<String, Object>> reverlists =lists;
        Collections.reverse(reverlists);

        SimpleAdapter adapter = new SimpleAdapter(getContext(), lists, R.layout.history
                , new String[]{"kuaidi", "date"}
                , new int[]{R.id.history_detial, R.id.date});
        listView.setAdapter(adapter);





        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                if (istracked&&status==1&&position==0)return;
                position = packageRoutes.size() - 1 - position;
                if (istracked&&status==1) position++;
                LatLngBounds.Builder b = LatLngBounds.builder();

                b.include(new LatLng(packageRoutes.get(position).getX() - 0.030, packageRoutes.get(position).getY() - 0.004));
                b.include(new LatLng(packageRoutes.get(position).getX() + 0.019, packageRoutes.get(position).getY() + 0.004));
                aMap.animateCamera(CameraUpdateFactory
                        .newLatLngBounds(b.build(), 50));
                if (istracked&&status==1) position--;
            }
        });
//        Toast.makeText(getContext(), packageRoutes.size() + "个标记", Toast.LENGTH_LONG).show();
    }

//        if(latLonPoints.size()>1)


//        private void init2 (List < LatLng > latLngs) {
//
////            RouteSearch routeSearch = new RouteSearch(this.mContext);
////            routeSearch.setRouteSearchListener(this);
////            final RouteSearch.FromAndTo fromAndTo = new RouteSearch.FromAndTo(
////                    latLonPoints.get(i), latLonPoints.get(i + 1));
////            DriveRouteQuery query = new DriveRouteQuery(fromAndTo, RouteSearch.DRIVING_SINGLE_DEFAULT, null, null, "");
////            routeSearch.calculateDriveRouteAsyn(query);
//        }
//    }

    private void init() {
        if (aMap == null) {
            aMap = mapView.getMap();
        }

        final RouteSearch.FromAndTo fromAndTo = new RouteSearch.FromAndTo(
                mStartPoint, mEndPoint);
        DriveRouteQuery query = new DriveRouteQuery(fromAndTo, RouteSearch.DRIVING_SINGLE_DEFAULT, null, null, "");
        routeSearch.calculateDriveRouteAsyn(query);

        //=============================

    }

    @Override
    public void onBusRouteSearched(BusRouteResult busRouteResult, int i) {

    }

    @Override
    public void onDriveRouteSearched(DriveRouteResult result, int errorCode) {
        //aMap.clear();// 清理地图上的所有覆盖物
        if (errorCode == AMapException.CODE_AMAP_SUCCESS) {
            if (result != null && result.getPaths() != null) {
                if (result.getPaths().size() > 0) {
                    mDriveRouteResult = result;
                    final DrivePath drivePath = mDriveRouteResult.getPaths()
                            .get(0);
                    DrivingRouteOverLay drivingRouteOverlay = new DrivingRouteOverLay(
                            mContext, aMap, drivePath,
                            mDriveRouteResult.getStartPos(),
                            mDriveRouteResult.getTargetPos(), null);
                    drivingRouteOverlay.setNodeIconVisibility(false);//设置节点marker是否显示
                    drivingRouteOverlay.setIsColorfulline(false);//是否用颜色展示交通拥堵情况，默认true
                    drivingRouteOverlay.removeFromMap();
                    drivingRouteOverlay.addToMap();
                    drivingRouteOverlay.zoomToSpan();

                } else if (result != null && result.getPaths() == null) {
                    ToastUtil.show(mContext, "no_result");
                }

            } else {
                ToastUtil.show(mContext, "no_result");
            }
        } else {
            ToastUtil.showerror(this.getContext(), errorCode);
        }


    }


    @Override
    public void onWalkRouteSearched(WalkRouteResult walkRouteResult, int i) {

    }
    protected List<Polyline> allPolyLines = new ArrayList<Polyline>();
    @Override
    public void onRideRouteSearched(RideRouteResult rideRouteResult, int i) {
        PolylineOptions mPolylineOptions;

        BitmapDescriptor walkStationDescriptor= null;


        final RidePath ridePath = rideRouteResult.getPaths()
                .get(0);

        mPolylineOptions = null;
        mPolylineOptions = new PolylineOptions();
        mPolylineOptions.color(Color.parseColor("#537edc")).width(15);
        try {
            List<RideStep> ridePaths = ridePath.getSteps();

            for (int j = 0; j < ridePaths.size(); j++) {
                RideStep rideStep = ridePaths.get(j);
                LatLng latLng = AMapUtil.convertToLatLng(rideStep
                        .getPolyline().get(0));


//                addRideStationMarkers(rideStep, latLng);
                mPolylineOptions.addAll(AMapUtil.convertArrList(rideStep.getPolyline()));
            }
//            mPolylineOptions.add(endPoint);
//            addStartAndEndMarker();

            addPolyLine(mPolylineOptions);
        } catch (Throwable e) {
            e.printStackTrace();
        }
    }
    private void addPolyLine(PolylineOptions options) {
        if(options == null) {
            return;
        }
        Polyline polyline = aMap.addPolyline(options);
        if(polyline != null) {
            allPolyLines.add(polyline);
        }
    }



    //==========================================================================================================
    public void track(final List<PackageRoute> packageRoutes, final Integer status, final List<String> address) {
        drawRoutes( packageRoutes,  status,  address);
        clearTracksOnMap();
        // 先查询terminal id，然后用terminal id查询轨迹
        // 查询符合条件的所有轨迹，并分别绘制
        aMapTrackClient.queryTerminal(new QueryTerminalRequest(Constants.SERVICE_ID, constants.TERMINAL_NAME), new SimpleOnTrackListener() {
            @Override
            public void onQueryTerminalCallback(final QueryTerminalResponse queryTerminalResponse) {
                if (queryTerminalResponse.isSuccess()) {
                    if (queryTerminalResponse.isTerminalExist()) {
                        long tid = queryTerminalResponse.getTid();
                        // 搜索最近12小时以内上报的属于某个轨迹的轨迹点信息，散点上报不会包含在该查询结果中
                        QueryTrackRequest queryTrackRequest = new QueryTrackRequest(
                                Constants.SERVICE_ID,
                                tid,
                                -1,
                                // 轨迹id，不指定，查询所有轨迹，注意分页仅在查询特定轨迹id时生效，查询所有轨迹时无法对轨迹点进行分页
                                System.currentTimeMillis() - 12 * 60 * 60 * 1000,
                                System.currentTimeMillis(),
                                0,      // 不启用去噪
                                0,   // 绑路
                                0,      // 不进行精度过滤
                                DriveMode.DRIVING,  // 当前仅支持驾车模式
                                0,     // 距离补偿
                                5000,   // 距离补偿，只有超过5km的点才启用距离补偿
                                1,  // 结果应该包含轨迹点信息
                                1,  // 返回第1页数据，但由于未指定轨迹，分页将失效
                                100    // 一页不超过100条
                        );
                        aMapTrackClient.queryTerminalTrack(queryTrackRequest, new SimpleOnTrackListener() {
                            @Override
                            public void onQueryTrackCallback(QueryTrackResponse queryTrackResponse) {
                                if (queryTrackResponse.isSuccess()) {
                                    List<Track> tracks = queryTrackResponse.getTracks();
                                    if (tracks != null && !tracks.isEmpty()) {
                                        boolean allEmpty = true;
                                        for (Track track : tracks) {
                                            List<Point> points = track.getPoints();
//  ================  ==================================================
//                                          ToastUtil.show(getContext(), String.valueOf(track.getTrid()));
                                            if (points != null && points.size() > 0) {
                                                allEmpty = false;
                                                drawTrackOnMap(points, track.getStartPoint(), track.getEndPoint());
                                            }
                                        }
                                        if (allEmpty) {
                                            Toast.makeText(mContext,
                                                    "所有轨迹都无轨迹点", Toast.LENGTH_SHORT).show();
                                        } else {
                                            StringBuilder sb = new StringBuilder();
                                            sb.append("共查询到").append(tracks.size()).append("条轨迹，每条轨迹行驶距离分别为：");
                                            for (Track track : tracks) {
                                                sb.append(track.getDistance()).append("m,");
                                            }
                                            sb.deleteCharAt(sb.length() - 1);


                                            istracked=true;
                                            drawRoutes( packageRoutes,  status,  address);

                                            Toast.makeText(mContext, sb.toString() + " " + queryTrackResponse.getTracks().get(0).getTrid() + "  " + queryTerminalResponse.getTid(), Toast.LENGTH_SHORT).show();
                                        }
                                    } else {
                                        Toast.makeText(mContext, "未获取到轨迹", Toast.LENGTH_SHORT).show();
                                    }
                                } else {
                                    Toast.makeText(mContext, "查询历史轨迹失败，" + queryTrackResponse.getErrorMsg(), Toast.LENGTH_SHORT).show();
                                }
                            }
                        });
                    } else {
//                        Toast.makeText(mContext, "Terminal不存在", Toast.LENGTH_SHORT).show();
                    }
                } else {
                    showNetErrorHint(queryTerminalResponse.getErrorMsg());
                }
            }
        });
    }

    private void showNetErrorHint(String errorMsg) {
        Toast.makeText(mContext, "网络请求失败，错误原因: " + errorMsg, Toast.LENGTH_SHORT).show();
    }

    private void drawTrackOnMap(List<Point> points, TrackPoint startPoint, TrackPoint
            endPoint) {
        LatLngBounds.Builder boundsBuilder = new LatLngBounds.Builder();
        PolylineOptions polylineOptions = new PolylineOptions();
        polylineOptions.color(Color.BLUE).width(20);

        if (startPoint != null && startPoint.getLocation() != null) {
            LatLng latLng = new LatLng(startPoint.getLocation().getLat(), startPoint.getLocation().getLng());
            MarkerOptions markerOptions = new MarkerOptions()
                    .position(latLng)
                    .icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_GREEN));
            endMarkers.add(mapView.getMap().addMarker(markerOptions));
        }

        if (endPoint != null && endPoint.getLocation() != null) {
            LatLng latLng = new LatLng(endPoint.getLocation().getLat(), endPoint.getLocation().getLng());
            Bitmap bitmap = null;
            if(getActivity()!=null){
                bitmap = Bitmap.createScaledBitmap(BitmapFactory.decodeResource(getActivity().getResources(), R.drawable.find_more_game), 80, 80, true);}
            MarkerOptions markerOptions = new MarkerOptions()
                    .position(latLng)
                    .icon(BitmapDescriptorFactory.fromBitmap(bitmap));
            markerOptions.title("派送轨迹");
            mapView.getMap().addMarker(markerOptions).showInfoWindow();
            endMarkers.add(mapView.getMap().addMarker(markerOptions));


        }

        for (Point p : points) {
            LatLng latLng = new LatLng(p.getLat(), p.getLng());
            polylineOptions.add(latLng);
            boundsBuilder.include(latLng);
        }
        Polyline polyline = mapView.getMap().addPolyline(polylineOptions);
        polylines.add(polyline);
        mapView.getMap().animateCamera(CameraUpdateFactory.newLatLngBounds(boundsBuilder.build(), 30));
    }

    private void clearTracksOnMap() {
        for (Polyline polyline : polylines) {
            polyline.remove();
        }
        for (Marker marker : endMarkers) {
            marker.remove();
        }
        endMarkers.clear();
        polylines.clear();
    }


}